package logging

import (
	"bytes"
	"fmt"
	"sync"
)

// DefaultSink 默认槽
type DefaultSink struct {
	formatter Formatter  // 格式化工具
	backends  []Backend  // 后端
	mu        sync.Mutex // 互斥体
	bufs      *sync.Pool // 缓存池
}

// SetFormatter 设置格式化工具
func (sink *DefaultSink) SetFormatter(formatter Formatter) {
	sink.formatter = formatter
}

// AddBackend 添加后端
func (sink *DefaultSink) AddBackend(backend Backend) {
	sink.backends = append(sink.backends, backend)
}

// Consume 消费日志记录
func (sink *DefaultSink) Consume(rec *Record) {
	sink.mu.Lock()
	defer sink.mu.Unlock()

	if sink.bufs == nil {
		sink.bufs = &sync.Pool{
			New: func() any {
				return new(bytes.Buffer)
			},
		}
	}

	// 设置默认格式化工具
	if sink.formatter == nil {
		sink.formatter = &TextFormatter{}
	}

	// 设置默认后端
	if len(sink.backends) == 0 {
		sink.backends = append(sink.backends, &StderrBackend{})
	}

	// 获取缓存
	buf := sink.bufs.Get().(*bytes.Buffer)
	buf.Reset()

	// 格式化日志
	err := sink.formatter.Format(rec, buf)
	if err != nil {
		panic(fmt.Sprintf("发生错误，日志退出: %v", err))
	}

	// 写日志
	for _, b := range sink.backends {
		if b.Filter(rec) {
			_, err := b.Write(buf.Bytes())
			if err != nil {
				panic(fmt.Sprintf("发生错误，日志退出: %v", err))
			}
		}
	}

	// 回收缓存
	sink.bufs.Put(buf)
}

// Close 关闭槽
func (sink *DefaultSink) Close() {
	for _, b := range sink.backends {
		b.Close()
	}
}
